/*
 * @Author: your name
 * @Date: 2021-12-14 08:50:43
 * @LastEditTime: 2022-07-12 14:13:45
 * @LastEditors: long qun
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \sys-natural-disaster\src\assets\js\GisTools.js
 *
 */
import * as Cesium from 'cesium'
import * as turf from '@turf/turf'

// transform
export const cartesian3ToDegree = (cartesian3) => {
  const cartographic = Cesium.Cartographic.fromCartesian(cartesian3)
  const lng = Cesium.Math.toDegrees(cartographic.longitude)
  const lat = Cesium.Math.toDegrees(cartographic.latitude)
  const degree = [lng, lat]
  return degree
}

// createRandomPoints
function createRandomPoints({
  length,
  jsonData,
  bbox = [114.882839, 29.393037, 119.649144, 34.650809],
  minValue = 0,
  maxValue = 100
}) {
  const heatPoints = []
  for (let i = 0; i < length; i++) {
    let isPointInPolygon = false
    let heatPoint = {}
    while (!isPointInPolygon) {
      const x = bbox[0] + Math.random() * (bbox[2] - bbox[0])
      const y = bbox[1] + Math.random() * (bbox[3] - bbox[1])
      const value = minValue + Math.random() * maxValue
      heatPoint = {
        x,
        y,
        value
      }
      const point = turf.point([x, y])
      isPointInPolygon = turf.booleanPointInPolygon(point, jsonData)
    }
    heatPoints.push(heatPoint)
  }
  return heatPoints
}

// drawing
export class MeasureDistance {
  constructor(viewer) {
    this.viewer = viewer
    // this.viewer.scene.globe.depthTestAgainstTerrain = true; //参考pickPosition和pickEpisoid
    this.initEvents()
    this.positions = []
    this.tempPositions = []
    this.vertexEntities = []
    this.labelEntity = undefined
    this.measureDistance = 0 //测量结果
    this.pixelSize = 6
  }

  //初始化事件
  initEvents() {
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    this.MeasureStartEvent = new Cesium.Event() //开始事件
    this.MeasureEndEvent = new Cesium.Event() //结束事件
  }

  //激活
  activate() {
    this.deactivate()
    this.registerEvents() //注册鼠标事件
    //设置鼠标状态
    this.viewer.enableCursorStyle = false
    this.viewer._element.style.cursor = 'default'
    this.isMeasure = true
    this.measureDistance = 0
  }

  //禁用
  deactivate() {
    if (!this.isMeasure) return
    this.unRegisterEvents()
    this.viewer._element.style.cursor = 'pointer'
    this.viewer.enableCursorStyle = true
    this.isMeasure = false
    this.tempPositions = []
    this.positions = []
  }

  //清空绘制
  clear() {
    //清除线对象
    this.viewer.entities.remove(this.lineEntity)
    this.lineEntity = {}

    //清除节点
    this.vertexEntities.forEach((item) => {
      this.viewer.entities.remove(item)
    })
    this.vertexEntities = []
  }

  //创建线对象
  createLineEntity() {
    this.lineEntity = this.viewer.entities.add({
      polyline: {
        positions: new Cesium.CallbackProperty(() => {
          return this.tempPositions
        }, false),
        width: 2,
        material: Cesium.Color.fromCssColorString('#4DFFFF'),
        depthFailMaterial: Cesium.Color.fromCssColorString('#4DFFFF')
      }
    })
  }

  //创建线节点
  spaceDistance(positions) {
    const length = Cesium.Cartesian3.distance(
      positions[positions.length - 1],
      positions[positions.length - 2]
    )

    this.measureDistance = this.measureDistance + length
    // this.measureDistance.toFixed(1);
    // return this.measureDistance.toFixed(1);
    return this.measureDistance
  }

  createVertex() {
    let text = ''
    if (this.spaceDistance(this.positions) > 1000) {
      text = (this.spaceDistance(this.positions) / 1000).toFixed(1) + '公里'
    } else {
      (text = this.spaceDistance(this.positions).toFixed(1) + '米')
    }
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      // id: 'MeasureDistanceVertex' + this.positions[this.positions.length - 1],
      type: 'MeasureDistanceVertex',
      label: {
        // text: spaceDistance(this.positions) + "米",
        // text: "米",
        // text: this.spaceDistance(this.positions) + "米",
        // text: getLengthText(this.positions),
        text: text,
        scale: 1.5,
        font: 'normal 20px MicroSoft YaHei',
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -10),
        outlineWidth: 6,
        outlineColor: Cesium.Color.BLACK,
        fillColor: Cesium.Color.WHITE
      },
      point: {
        color: Cesium.Color.RED,
        pixelSize: this.pixelSize,
        disableDepthTestDistance: 500
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //创建起点
  createStartEntity() {
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[0],
      type: 'MeasureDistanceVertex',
      label: {
        text: '起点',
        scale: 1.5,
        font: 'normal 20px MicroSoft YaHei',
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -10),
        outlineWidth: 6,
        outlineColor: Cesium.Color.BLACK,
        fillColor: Cesium.Color.WHITE
      },
      point: {
        color: Cesium.Color.RED,
        pixelSize: this.pixelSize
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //创建终点节点
  //因为我用的距离就是总距离，不是分段距离，所以最后一个EndEntity可以注释掉。不用。
  createEndEntity() {
    //结束时删除最后一个节点的距离标识
    const lastLabel = this.viewer.entities.getById(
      'MeasureDistanceVertex' + this.positions[this.positions.length - 1]
    )
    this.viewer.entities.remove(lastLabel)
    this.viewer.entities.remove(this.moveVertexEntity)

    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      type: 'MeasureDistanceVertex',
      label: {
        text: '总距离：' + this.spaceDistance(this.positions) + '米',
        scale: 1.5,
        font: 'normal 20px MicroSoft YaHei',
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        eyeOffset: new Cesium.Cartesian3(0, 0, -10),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -20),
        outlineWidth: 6,
        outlineColor: Cesium.Color.BLACK,
        fillColor: Cesium.Color.WHITE
      },
      billboard: {
        image: '',
        scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4), //设置随图缩放距离和比例
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), //设置可见距离 10000米可见
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
      point: {
        color: Cesium.Color.RED,
        pixelSize: this.pixelSize
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //注册鼠标事件
  registerEvents() {
    this.leftClickEvent()
    this.rightClickEvent()
    this.mouseMoveEvent()
  }

  //左键点击事件
  leftClickEvent() {
    //单击鼠标左键画点点击事件
    this.handler.setInputAction((e) => {
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.position)
      //使用pickPosition有两个问题，1 不加地形侦测this.viewer.scene.globe.depthTestAgainstTerrain = true的话，
      //移动鼠标，点会飘逸，而且受地形影响时而看见，时而看不见。2，加了地形侦测，点会被隐藏一半，不知道怎么调整。
      //所以在没有地形的情况下，先用pickEllipsoid（据说在有地形的情况下，坐标有偏差）。
      //   if (!position) {
      // if (true)
      // {
      const ellipsoid = this.viewer.scene.globe.ellipsoid
      position = this.viewer.scene.camera.pickEllipsoid(
        e.position,
        ellipsoid
      )
      // }

      if (!position) return
      this.positions.push(position)
      if (this.positions.length === 1) {
        //首次点击
        this.createLineEntity()
        this.createStartEntity()
        return
      }
      this.createVertex()
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    this.handler.setInputAction(() => {
      if (!this.isMeasure || this.positions.length < 1) {
        this.deactivate()
        // this.clear();
      } else {
        // this.createEndEntity();
        // this.createVertex();
        this.lineEntity.polyline = {
          positions: this.positions,
          width: 2,
          material: Cesium.Color.fromCssColorString('#4DFFFF'),
          depthFailMaterial: Cesium.Color.fromCssColorString('#4DFFFF')
        }
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }

  //鼠标移动事件
  mouseMoveEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure) return
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.endPosition)
      if (!position) {
        position = this.viewer.scene.camera.pickEllipsoid(
          e.startPosition,
          this.viewer.scene.globe.ellipsoid
        )
      }
      if (!position) return
      this.handleMoveEvent(position)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  //处理鼠标移动
  handleMoveEvent(position) {
    if (this.positions.length < 1) return
    this.tempPositions = this.positions.concat(position)
  }

  //右键事件deactivate
  rightClickEvent() {
    this.handler.setInputAction(() => {
      if (!this.isMeasure || this.positions.length < 1) {
        this.deactivate()
        this.clear()
      } else {
        // this.createEndEntity();
        // this.createVertex();
        this.lineEntity.polyline = {
          positions: this.positions,
          width: 2,
          material: Cesium.Color.fromCssColorString('#4DFFFF'),
          depthFailMaterial: Cesium.Color.fromCssColorString('#4DFFFF')
        }
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
  }

  //测量结束
  measureEnd() {
    this.deactivate()
    this.MeasureEndEvent.raiseEvent(this.measureDistance) //触发结束事件 传入结果
  }

  //解除鼠标事件
  unRegisterEvents() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}

export class measureArea {
  constructor(viewer) {
    this.viewer = viewer
    this.initEvents()
    this.positions = []
    this.tempPositions = []
    this.vertexEntities = []
    this.labelEntity = undefined
    this.measureArea = 0 //测量结果
  }

  //初始化事件
  initEvents() {
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    this.MeasureStartEvent = new Cesium.Event() //开始事件
    this.MeasureEndEvent = new Cesium.Event() //结束事件
  }

  //激活
  activate() {
    this.deactivate()
    this.registerEvents() //注册鼠标事件
    //设置鼠标状态
    this.viewer.enableCursorStyle = false
    this.viewer._element.style.cursor = 'default'
    this.isMeasure = true
    this.measureArea = 0
  }

  //禁用
  deactivate() {
    if (!this.isMeasure) return
    this.unRegisterEvents()
    this.viewer._element.style.cursor = 'pointer'
    this.viewer.enableCursorStyle = true
    this.isMeasure = false
    this.tempPositions = []
    this.positions = []
    this.height = undefined
  }

  //清空绘制
  clear() {
    //清除线面对象
    this.viewer.entities.remove(this.polygonEntity)
    this.polygonEntity = undefined

    //清除节点
    this.vertexEntities.forEach((item) => {
      this.viewer.entities.remove(item)
    })
    this.vertexEntities = []

    this.viewer.entities.remove(this.mesureResultEntity)
    this.mesureResultEntity = undefined

    this.height = undefined
  }

  //创建面对象
  createPolygonEntity() {
    this.polygonEntity = this.viewer.entities.add({
      polygon: {
        hierarchy: new Cesium.CallbackProperty((e) => {
          return new Cesium.PolygonHierarchy(this.tempPositions)
          //使用最新1.72的时候 必须返回PolygonHierarchy类型 Cannot read property 'length' of undefined
          //低版本好像都可以
        }, false),
        material: Cesium.Color.RED.withAlpha(0.4),
        perPositionHeight: true //
      },
      polyline: {
        positions: new Cesium.CallbackProperty((e) => {
          return this.tempPositions.concat(this.tempPositions[0])
        }, false),
        width: 1,
        material: new Cesium.PolylineDashMaterialProperty({
          color: Cesium.Color.YELLOW
        }),
        depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
          color: Cesium.Color.YELLOW
        })
      }
    })
  }

  //创建节点
  createVertex() {
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      type: 'MeasureAreaVertex',
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: 8,
        disableDepthTestDistance: 500
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //测量结果标签
  createResultLabel() {
    this.mesureResultEntity = this.viewer.entities.add({
      position: new Cesium.CallbackProperty((e) => {
        return this.getCenterPosition()
      }, false),
      type: 'MeasureAreaResult',
      label: {
        text: new Cesium.CallbackProperty((e) => {
          if (this.computeArea(this.tempPositions) > 1000000) {
            const area = this.computeArea(this.tempPositions) / 1000000
            return area.toFixed(1) + '平方公里'
          } else {
            return this.computeArea(this.tempPositions).toFixed(1) + '平方米'
          }
        }, false),

        scale: 1,
        font: 'normal 28px MicroSoft YaHei',
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -30),
        outlineWidth: 9,
        outlineColor: Cesium.Color.YELLOW
      }
    })
  }

  //获取节点的中心点
  getCenterPosition() {
    const points = []
    if (this.tempPositions.length < 3) return this.tempPositions[0]
    this.tempPositions.forEach((position) => {
      const point3d = this.cartesian3ToPoint3D(position)
      points.push([point3d.x, point3d.y])
    })

    //构建turf.js  lineString
    const geo = turf.lineString(points)
    const bbox = turf.bbox(geo)
    const bboxPolygon = turf.bboxPolygon(bbox)
    const pointOnFeature = turf.center(bboxPolygon)
    const lonLat = pointOnFeature.geometry.coordinates

    return Cesium.Cartesian3.fromDegrees(
      lonLat[0],
      lonLat[1],
      this.height + 0.3
    )
  }

  //注册鼠标事件
  registerEvents() {
    this.leftClickEvent()

    this.rightClickEvent()
    this.mouseMoveEvent()
  }

  //左键点击事件
  leftClickEvent() {
    //单击鼠标左键画点点击事件

    this.handler.setInputAction((e) => {
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.position)
      //   if (!position) {
      // if (true)
      // {
      const ellipsoid = this.viewer.scene.globe.ellipsoid
      position = this.viewer.scene.camera.pickEllipsoid(
        e.position,
        ellipsoid
      )
      // }
      if (!position) return
      this.positions.push(position)
      this.height = this.unifiedHeight(this.positions, this.height)
      if (this.positions.length === 1) {
        //首次点击
        this.createPolygonEntity()
      }
      this.createVertex()
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    this.handler.setInputAction((e) => {
      /*     console.log('isMeasure:' + this.isMeasure)
      console.log('positions.length' + this.positions.length)
      console.log('area:leftClickEvent函数') */
      if (!this.isMeasure || this.positions.length < 4) {
        this.deactivate()
        this.clear()
      } else {
        this.tempPositions = [...this.positions]
        this.polygonEntity.polyline = {
          positions: this.positions.concat(this.positions[0]),
          width: 2,
          material: Cesium.Color.YELLOW,
          depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.YELLOW
          })
        }

        this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(
          this.tempPositions
        )
        this.mesureResultEntity.position = this.getCenterPosition()
        if (this.computeArea(this.tempPositions) > 1000000) {
          const area = this.computeArea(this.tempPositions) / 1000000
          this.mesureResultEntity.label.text =
            area.toFixed(1) + '平方公里'
        } else {
          this.mesureResultEntity.label.text =
            this.computeArea(this.positions).toFixed(1) + '平方米'
        }

        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }

  //鼠标移动事件
  mouseMoveEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure) return
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.endPosition)
      if (!position) {
        position = this.viewer.scene.camera.pickEllipsoid(
          e.startPosition,
          this.viewer.scene.globe.ellipsoid
        )
      }
      if (!position) return
      this.handleMoveEvent(position)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  //处理鼠标移动
  handleMoveEvent(position) {
    if (this.positions.length < 1) return

    this.height = this.unifiedHeight(this.positions, this.height)
    this.tempPositions = this.positions.concat(position)
    if (this.tempPositions.length >= 3 && !this.mesureResultEntity) {
      this.createResultLabel()
    }
  }

  //统一节点的高度
  unifiedHeight(positions, height) {
    if (!height) height = this.getPositionHeight(positions[0]) //如果没有指定高度 就用第一个的高度
    let point3d
    for (let i = 0; i < positions.length; i++) {
      const element = positions[i]
      point3d = this.cartesian3ToPoint3D(element)
      positions[i] = Cesium.Cartesian3.fromDegrees(
        point3d.x,
        point3d.y,
        height
      )
    }

    return height
  }

  //获取某个点的高度
  getPositionHeight(position) {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    return cartographic.height
  }

  cartesian3ToPoint3D(position) {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    const lon = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)
    return {
      x: lon,
      y: lat,
      z: cartographic.height
    }
  }

  //右键事件
  rightClickEvent() {
    this.handler.setInputAction((e) => {
      /*    console.log('isMeasure:' + this.isMeasure)
      console.log('positions.length' + this.positions.length) */
      if (!this.isMeasure || this.positions.length < 3) {
        this.deactivate()
        this.clear()
      } else {
        this.tempPositions = [...this.positions]
        this.polygonEntity.polyline = {
          positions: this.positions.concat(this.positions[0]),
          width: 2,
          material: Cesium.Color.YELLOW,
          depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.YELLOW
          })
        }

        this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(
          this.tempPositions
        )
        this.mesureResultEntity.position = this.getCenterPosition()
        if (this.computeArea(this.tempPositions) > 1000000) {
          const area = this.computeArea(this.tempPositions) / 1000000
          this.mesureResultEntity.label.text =
            area.toFixed(1) + '平方公里'
        } else {
          this.mesureResultEntity.label.text =
            this.computeArea(this.positions).toFixed(1) + '平方米'
        }

        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
  }

  //测量结束
  measureEnd() {
    this.deactivate()
    this.MeasureEndEvent.raiseEvent(this.measureArea) //触发结束事件 传入结果
  }

  computeArea(positions) {
    const lnsLats = []

    positions[positions.length] = positions[0]
    for (let i = 0; i < positions.length; i++) {
      const cartographic = Cesium.Cartographic.fromCartesian(positions[i])
      const lng = Cesium.Math.toDegrees(cartographic.longitude)
      const lat = Cesium.Math.toDegrees(cartographic.latitude)
      lnsLats.push([lng, lat])
    }
    if (lnsLats.length >= 4) {
      const polygon = turf.polygon([

        lnsLats
      ])
      this.measureArea = turf.area(polygon)
      return this.measureArea
    } else {
      return 200
    }
  }

  //解除鼠标事件
  unRegisterEvents() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}

export class plotPolyline {
  constructor({ viewer, name = 'name', description = 'description', outlineColor = Cesium.Color.YELLOW, material = Cesium.Color.YELLOW, outlineWidth = 1, alpha = 1 }) {
    this.viewer = viewer
    // this.viewer.scene.globe.depthTestAgainstTerrain = true; //参考pickPosition和pickEpisoid
    this.initEvents()
    this.positions = []
    this.tempPositions = []
    this.vertexEntities = []
    this.labelEntity = undefined
    this.measureDistance = 0 //测量结果
    this.pixelSize = 6

    this.name = name
    this.description = description
    this.outlineColor = outlineColor
    this.material = material
    this.outlineWidth = outlineWidth
    this.alpha = alpha
  }

  //初始化事件
  initEvents() {
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    this.MeasureStartEvent = new Cesium.Event() //开始事件
    this.MeasureEndEvent = new Cesium.Event() //结束事件
  }

  //激活
  activate() {
    this.deactivate()
    this.registerEvents() //注册鼠标事件
    //设置鼠标状态
    this.viewer.enableCursorStyle = false
    this.viewer._element.style.cursor = 'default'
    this.isMeasure = true
    this.measureDistance = 0
  }

  //禁用
  deactivate() {
    if (!this.isMeasure) return
    this.unRegisterEvents()
    this.viewer._element.style.cursor = 'pointer'
    this.viewer.enableCursorStyle = true
    this.isMeasure = false
    this.tempPositions = []
    this.positions = []
  }

  //清空绘制
  clear() {
    //清除线对象
    this.viewer.entities.remove(this.lineEntity)
    this.lineEntity = {}

    //清除节点
    this.vertexEntities.forEach((item) => {
      this.viewer.entities.remove(item)
    })
    this.vertexEntities = []
  }

  //创建线对象
  createLineEntity() {
    this.lineEntity = this.viewer.entities.add({
      polyline: {
        positions: new Cesium.CallbackProperty(() => {
          return this.tempPositions
        }, false),
        width: this.outlineWidth,
        material: this.material,
        depthFailMaterial: this.material
      }
    })
  }

  //创建线节点
  spaceDistance(positions) {
    const length = Cesium.Cartesian3.distance(
      positions[positions.length - 1],
      positions[positions.length - 2]
    )

    this.measureDistance = this.measureDistance + length
    // this.measureDistance.toFixed(1);
    // return this.measureDistance.toFixed(1);
    return this.measureDistance
  }

  createVertex() {
    let text = ''
    if (this.spaceDistance(this.positions) > 1000) {
      text = (this.spaceDistance(this.positions) / 1000).toFixed(1) + '公里'
    } else {
      (text = this.spaceDistance(this.positions).toFixed(1) + '米')
    }
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      // id: 'MeasureDistanceVertex' + this.positions[this.positions.length - 1],
      type: 'MeasureDistanceVertex',
      label: {
        // text: spaceDistance(this.positions) + "米",
        // text: "米",
        // text: this.spaceDistance(this.positions) + "米",
        // text: getLengthText(this.positions),
        text: text,
        scale: 1.5,
        font: 'normal 24px MicroSoft YaHei',
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -10),
        outlineWidth: 12,
        outlineColor: Cesium.Color.WHITE,
        fillColor: Cesium.Color.RED
      },
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: this.pixelSize,
        disableDepthTestDistance: 500
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //创建起点
  createStartEntity() {
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[0],
      type: 'MeasureDistanceVertex',
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: this.pixelSize
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //创建终点节点
  //因为我用的距离就是总距离，不是分段距离，所以最后一个EndEntity可以注释掉。不用。
  createEndEntity() {
    //结束时删除最后一个节点的距离标识
    const lastLabel = this.viewer.entities.getById(
      'MeasureDistanceVertex' + this.positions[this.positions.length - 1]
    )
    this.viewer.entities.remove(lastLabel)
    this.viewer.entities.remove(this.moveVertexEntity)

    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      type: 'MeasureDistanceVertex',
      label: {
        text: '总距离：' + this.spaceDistance(this.positions) + '米',
        scale: 1.5,
        font: 'normal 26px MicroSoft YaHei',
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -20),
        outlineWidth: 15,
        outlineColor: Cesium.Color.WHITE,
        eyeOffset: new Cesium.Cartesian3(0, 0, -10),
        fillColor: Cesium.Color.RED
      },
      billboard: {
        image: '../Data/images/end.png',
        scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4), //设置随图缩放距离和比例
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), //设置可见距离 10000米可见
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: this.pixelSize
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //注册鼠标事件
  registerEvents() {
    this.leftClickEvent()
    this.rightClickEvent()
    this.mouseMoveEvent()
  }

  //左键点击事件
  leftClickEvent() {
    //单击鼠标左键画点点击事件
    this.handler.setInputAction((e) => {
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.position)
      //使用pickPosition有两个问题，1 不加地形侦测this.viewer.scene.globe.depthTestAgainstTerrain = true的话，
      //移动鼠标，点会飘逸，而且受地形影响时而看见，时而看不见。2，加了地形侦测，点会被隐藏一半，不知道怎么调整。
      //所以在没有地形的情况下，先用pickEllipsoid（据说在有地形的情况下，坐标有偏差）。
      //   if (!position) {
      // if (true)
      // {
      const ellipsoid = this.viewer.scene.globe.ellipsoid
      position = this.viewer.scene.camera.pickEllipsoid(
        e.position,
        ellipsoid
      )
      // }

      if (!position) return
      this.positions.push(position)
      if (this.positions.length === 1) {
        //首次点击
        this.createLineEntity()
        // this.createStartEntity()
        // return
      }
      // this.createVertex()
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    this.handler.setInputAction(() => {
      if (!this.isMeasure || this.positions.length < 1) {
        this.deactivate()
        this.clear()
      } else {
        // this.createEndEntity();
        // this.createVertex();
        this.lineEntity.polyline = {
          positions: this.positions,
          width: this.outlineWidth,
          material: this.material,
          depthFailMaterial: this.material
        }
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }

  //鼠标移动事件
  mouseMoveEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure) return
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.endPosition)
      if (!position) {
        position = this.viewer.scene.camera.pickEllipsoid(
          e.startPosition,
          this.viewer.scene.globe.ellipsoid
        )
      }
      if (!position) return
      this.handleMoveEvent(position)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  //处理鼠标移动
  handleMoveEvent(position) {
    if (this.positions.length < 1) return
    this.tempPositions = this.positions.concat(position)
  }

  //右键事件deactivate
  rightClickEvent() {
    this.handler.setInputAction(() => {
      if (!this.isMeasure || this.positions.length < 1) {
        this.deactivate()
        this.clear()
      } else {
        // this.createEndEntity();
        // this.createVertex();
        this.lineEntity.polyline = {
          positions: this.positions,
          width: 2,
          material: this.outlineColor,
          depthFailMaterial: Cesium.Color.YELLOW
        }
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
  }

  //测量结束
  measureEnd() {
    this.deactivate()
    this.MeasureEndEvent.raiseEvent(this.measureDistance) //触发结束事件 传入结果
  }

  //解除鼠标事件
  unRegisterEvents() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}

export class plotPolygon {
  constructor({ viewer, name = 'name', description = 'description', outlineColor = Cesium.Color.YELLOW, outlineWidth = 1, material = Cesium.Color.RED, alpha = 1 }) {
    this.viewer = viewer
    this.initEvents()
    this.positions = []
    this.tempPositions = []
    this.vertexEntities = []
    this.labelEntity = undefined
    this.measureArea = 0 //测量结果

    this.name = name
    this.description = description
    this.outlineColor = outlineColor
    this.outlineWidth = outlineWidth
    this.material = material
    this.alpha = alpha
  }

  //初始化事件
  initEvents() {
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    this.MeasureStartEvent = new Cesium.Event() //开始事件
    this.MeasureEndEvent = new Cesium.Event() //结束事件
  }

  //激活
  activate() {
    this.deactivate()
    this.registerEvents() //注册鼠标事件
    //设置鼠标状态
    this.viewer.enableCursorStyle = false
    this.viewer._element.style.cursor = 'default'
    this.isMeasure = true
    this.measureArea = 0
  }

  //禁用
  deactivate() {
    if (!this.isMeasure) return
    this.unRegisterEvents()
    this.viewer._element.style.cursor = 'pointer'
    this.viewer.enableCursorStyle = true
    this.isMeasure = false
    this.tempPositions = []
    this.positions = []
    this.height = undefined
  }

  //清空绘制
  clear() {
    //清除线面对象
    this.viewer.entities.remove(this.polygonEntity)
    this.polygonEntity = undefined

    //清除节点
    this.vertexEntities.forEach((item) => {
      this.viewer.entities.remove(item)
    })
    this.vertexEntities = []

    this.viewer.entities.remove(this.mesureResultEntity)
    this.mesureResultEntity = undefined

    this.height = undefined
  }

  //创建面对象
  createPolygonEntity() {
    this.polygonEntity = this.viewer.entities.add({
      polygon: {
        hierarchy: new Cesium.CallbackProperty((e) => {
          return new Cesium.PolygonHierarchy(this.tempPositions)
          //使用最新1.72的时候 必须返回PolygonHierarchy类型 Cannot read property 'length' of undefined
          //低版本好像都可以
        }, false),
        material: Cesium.Color.RED.withAlpha(0.4),
        perPositionHeight: true //
      },
      polyline: {
        positions: new Cesium.CallbackProperty((e) => {
          return this.tempPositions.concat(this.tempPositions[0])
        }, false),
        width: this.outlineWidth,
        material: this.outlineColor,
        depthFailMaterial: this.outlineColor
      }
    })
  }

  //创建节点
  createVertex() {
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      type: 'MeasureAreaVertex',
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: 8,
        disableDepthTestDistance: 500
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //测量结果标签
  createResultLabel() {
    this.mesureResultEntity = this.viewer.entities.add({
      position: new Cesium.CallbackProperty((e) => {
        return this.getCenterPosition()
      }, false),
      type: 'MeasureAreaResult',
      label: {
        /*   text: new Cesium.CallbackProperty((e) => {
            if (this.computeArea(this.tempPositions) > 1000000)
            {
              const area = this.computeArea(this.tempPositions) / 1000000
              return area.toFixed(1) + '平方公里'
            } else
            {
              return this.computeArea(this.tempPositions).toFixed(1) + '平方米'
            }
          }, false), */
        text: this.name,

        scale: 1,
        font: 'normal 28px MicroSoft YaHei',
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -30),
        outlineWidth: 9,
        outlineColor: Cesium.Color.YELLOW
      }
    })
  }

  //获取节点的中心点
  getCenterPosition() {
    const points = []
    if (this.tempPositions.length < 3) return this.tempPositions[0]
    this.tempPositions.forEach((position) => {
      const point3d = this.cartesian3ToPoint3D(position)
      points.push([point3d.x, point3d.y])
    })

    //构建turf.js  lineString
    const geo = turf.lineString(points)
    const bbox = turf.bbox(geo)
    const bboxPolygon = turf.bboxPolygon(bbox)
    const pointOnFeature = turf.center(bboxPolygon)
    const lonLat = pointOnFeature.geometry.coordinates

    return Cesium.Cartesian3.fromDegrees(
      lonLat[0],
      lonLat[1],
      this.height + 0.3
    )
  }

  //注册鼠标事件
  registerEvents() {
    this.leftClickEvent()

    this.rightClickEvent()
    this.mouseMoveEvent()
  }

  //左键点击事件
  leftClickEvent() {
    //单击鼠标左键画点点击事件
    this.handler.setInputAction((e) => {
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.position)

      const ellipsoid = this.viewer.scene.globe.ellipsoid
      position = this.viewer.scene.camera.pickEllipsoid(
        e.position,
        ellipsoid
      )

      if (!position) return
      this.positions.push(position)
      this.height = this.unifiedHeight(this.positions, this.height)
      if (this.positions.length === 1) {
        //首次点击
        this.createPolygonEntity()
      }
      // this.createVertex()
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    this.handler.setInputAction((e) => {
      if (!this.isMeasure || this.positions.length < 4) {
        this.deactivate()
        this.clear()
      } else {
        this.tempPositions = [...this.positions]
        this.polygonEntity.polyline = {
          positions: this.positions.concat(this.positions[0]),
          width: this.outlineWidth,
          material: this.outlineColor,
          depthFailMaterial: this.outlineColor
        }

        this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(
          this.tempPositions
        )
        this.polygonEntity.polygon.material = this.material

        this.mesureResultEntity.position = this.getCenterPosition()
        /*    if (this.computeArea(this.tempPositions) > 1000000)
        {
          const area = this.computeArea(this.tempPositions) / 1000000
          this.mesureResultEntity.label.text =
            area.toFixed(1) + '平方公里'
        } else
        {
          this.mesureResultEntity.label.text =
            this.computeArea(this.positions).toFixed(1) + '平方米'
        } */
        this.mesureResultEntity.label.text = this.name
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }

  //鼠标移动事件
  mouseMoveEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure) return
      this.viewer._element.style.cursor = 'default'
      let position = this.viewer.scene.pickPosition(e.endPosition)
      if (!position) {
        position = this.viewer.scene.camera.pickEllipsoid(
          e.startPosition,
          this.viewer.scene.globe.ellipsoid
        )
      }
      if (!position) return
      this.handleMoveEvent(position)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  //处理鼠标移动
  handleMoveEvent(position) {
    if (this.positions.length < 1) return

    this.height = this.unifiedHeight(this.positions, this.height)
    this.tempPositions = this.positions.concat(position)
    if (this.tempPositions.length >= 3 && !this.mesureResultEntity) {
      this.createResultLabel()
    }
  }

  //统一节点的高度
  unifiedHeight(positions, height) {
    if (!height) height = this.getPositionHeight(positions[0]) //如果没有指定高度 就用第一个的高度
    let point3d
    for (let i = 0; i < positions.length; i++) {
      const element = positions[i]
      point3d = this.cartesian3ToPoint3D(element)
      positions[i] = Cesium.Cartesian3.fromDegrees(
        point3d.x,
        point3d.y,
        height
      )
    }

    return height
  }

  //获取某个点的高度
  getPositionHeight(position) {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    return cartographic.height
  }

  cartesian3ToPoint3D(position) {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    const lon = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)
    return {
      x: lon,
      y: lat,
      z: cartographic.height
    }
  }

  //右键事件
  rightClickEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure || this.positions.length < 3) {
        this.deactivate()
        this.clear()
      } else {
        this.tempPositions = [...this.positions]
        this.polygonEntity.polyline = {
          positions: this.positions.concat(this.positions[0]),
          width: this.outlineWidth,
          material: this.outlineColor,
          depthFailMaterial: this.outlineColor
        }

        this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(
          this.tempPositions
        )
        this.polygonEntity.polygon.material = this.material
        this.mesureResultEntity.position = this.getCenterPosition()
        /*    if (this.computeArea(this.tempPositions) > 1000000)
        {
          const area = this.computeArea(this.tempPositions) / 1000000
          this.mesureResultEntity.label.text =
            area.toFixed(1) + '平方公里'
        } else
        {
          this.mesureResultEntity.label.text =
            this.computeArea(this.positions).toFixed(1) + '平方米'
        } */
        this.mesureResultEntity.label.text = this.name
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
  }

  //测量结束
  measureEnd() {
    this.deactivate()
    this.MeasureEndEvent.raiseEvent(this.measureArea) //触发结束事件 传入结果
  }

  computeArea(positions) {
    const lnsLats = []

    positions[positions.length] = positions[0]
    for (let i = 0; i < positions.length; i++) {
      const cartographic = Cesium.Cartographic.fromCartesian(positions[i])
      const lng = Cesium.Math.toDegrees(cartographic.longitude)
      const lat = Cesium.Math.toDegrees(cartographic.latitude)
      lnsLats.push([lng, lat])
    }
    if (lnsLats.length >= 4) {
      const polygon = turf.polygon([

        lnsLats
      ])
      this.measureArea = turf.area(polygon)
      return this.measureArea
    } else {
      return 200
    }
  }

  //解除鼠标事件
  unRegisterEvents() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}

export class plotCircle {
  constructor({ viewer, name = 'name', description = 'description', outlineColor = Cesium.Color.YELLOW, outlineWidth = 1, material = Cesium.Color.RED, alpha = 1 }) {
    this.viewer = viewer
    this.initEvents()
    this.positions = []
    this.tempPositions = []
    this.vertexEntities = []
    this.labelEntity = undefined
    this.measureArea = 0 //测量结果

    this.name = name
    this.description = description
    this.outlineColor = outlineColor
    this.outlineWidth = outlineWidth
    this.material = material
    this.alpha = alpha
  }

  //初始化事件
  initEvents() {
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    this.MeasureStartEvent = new Cesium.Event() //开始事件
    this.MeasureEndEvent = new Cesium.Event() //结束事件
  }

  //激活
  activate() {
    this.deactivate()
    this.registerEvents() //注册鼠标事件
    //设置鼠标状态
    // this.viewer.enableCursorStyle = false
    // this.viewer._element.style.cursor = 'default'
    this.isMeasure = true
    this.measureArea = 0
  }

  //禁用
  deactivate() {
    if (!this.isMeasure) return
    this.unRegisterEvents()
    // this.viewer._element.style.cursor = 'pointer'
    // this.viewer.enableCursorStyle = true
    this.isMeasure = false
    this.tempPositions = []
    this.positions = []
    this.height = undefined
  }

  //清空绘制
  clear() {
    //清除线面对象
    this.viewer.entities.remove(this.polygonEntity)
    this.polygonEntity = undefined

    //清除节点
    this.vertexEntities.forEach((item) => {
      this.viewer.entities.remove(item)
    })
    this.vertexEntities = []

    this.viewer.entities.remove(this.mesureResultEntity)
    this.mesureResultEntity = undefined

    this.height = undefined
  }

  //创建面对象
  createPolygonEntity() {
    this.polygonEntity = this.viewer.entities.add({
      position: this.positions[0],
      polygon: {
        hierarchy: new Cesium.CallbackProperty((e) => {
          return new Cesium.PolygonHierarchy(this.tempPositions)
          //使用最新1.72的时候 必须返回PolygonHierarchy类型 Cannot read property 'length' of undefined
          //低版本好像都可以
        }, false),
        material: Cesium.Color.RED.withAlpha(0.4),
        perPositionHeight: true //
      },
      polyline: {
        /* positions: new Cesium.CallbackProperty((e) => {
            return this.tempPositions.concat(this.tempPositions[0])
          }, false),  */
        positions: new Cesium.CallbackProperty((e) => {
          return this.tempPositions
        }, false),
        width: 1,
        material: Cesium.Color.RED.withAlpha(0.5),
        depthFailMaterial: this.outlineColor
      },

      ellipse: {
        semiMinorAxis: new Cesium.CallbackProperty(() => {
          // console.log(this.tempPositions.length)
          if (this.tempPositions.length >= 2) {
            // console.log(this.tempPositions)
            return Cesium.Cartesian3.distance(this.tempPositions[0], this.tempPositions[1])
          }
          return 0.00001
        }, false),
        semiMajorAxis: new Cesium.CallbackProperty(() => {
          if (this.tempPositions.length >= 2) {
            return Cesium.Cartesian3.distance(this.tempPositions[0], this.tempPositions[1])
          }
          return 0.00001
        }, false),

        material: Cesium.Color.BLUE.withAlpha(0.3), //可设置不同的MaterialProperty
        outline: true,
        outlineColor: Cesium.Color.YELLOW,
        outlineWidth: 2
      }

    })
  }

  //创建节点
  createVertex() {
    const vertexEntity = this.viewer.entities.add({
      position: this.positions[this.positions.length - 1],
      type: 'MeasureAreaVertex',
      point: {
        color: Cesium.Color.FUCHSIA,
        pixelSize: 8,
        disableDepthTestDistance: 500
      }
    })
    this.vertexEntities.push(vertexEntity)
  }

  //测量结果标签
  createResultLabel() {
    this.mesureResultEntity = this.viewer.entities.add({
      position: this.positions[0],
      type: 'MeasureAreaResult',
      label: {
        text: this.name,
        scale: 1,
        font: 'normal 28px MicroSoft YaHei',
        scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -30),
        outlineWidth: 9,
        outlineColor: Cesium.Color.YELLOW
      }
    })
  }

  //获取节点的中心点
  getCenterPosition() {
    const points = []
    if (this.tempPositions.length < 3) return this.tempPositions[0]
    this.tempPositions.forEach((position) => {
      const point3d = this.cartesian3ToPoint3D(position)
      points.push([point3d.x, point3d.y])
    })

    //构建turf.js  lineString
    const geo = turf.lineString(points)
    const bbox = turf.bbox(geo)
    const bboxPolygon = turf.bboxPolygon(bbox)
    const pointOnFeature = turf.center(bboxPolygon)
    const lonLat = pointOnFeature.geometry.coordinates

    return Cesium.Cartesian3.fromDegrees(
      lonLat[0],
      lonLat[1],
      this.height + 0.3
    )
  }

  //注册鼠标事件
  registerEvents() {
    this.leftClickEvent()
    // this.rightClickEvent()
    this.mouseMoveEvent()
  }

  //左键点击事件
  leftClickEvent() {
    //单击鼠标左键画点点击事件
    this.handler.setInputAction((e) => {
      // this.viewer._element.style.cursor = 'default'

      const ellipsoid = this.viewer.scene.globe.ellipsoid
      const position = this.viewer.scene.camera.pickEllipsoid(
        e.position,
        ellipsoid
      )

      if (!position) return
      this.positions.push(position)
      // console.log('position', position)
      // console.log('this.positions', this.positions)
      // this.height = this.unifiedHeight(this.positions, this.height)
      if (this.positions.length === 1) {
        //首次点击
        this.createPolygonEntity()
      }
      if (this.positions.length === 2) {
        // console.log(this.positions)

        const centerDegree = cartesian3ToDegree(this.positions[0])
        const options = { units: 'meters' }
        const radius = Cesium.Cartesian3.distance(this.positions[0], this.positions[1])
        const circle = turf.circle(centerDegree, radius, options)
        console.log('procircle', circle)
        circle.geometry.coordinates.flat()
        console.log('after', circle)
        circle.geometry.type = 'LineString'
        console.log(circle)
        this.polygonEntity.ellipse = {
          semiMinorAxis: radius,
          semiMajorAxis: radius,
          material: this.material, //可设置不同的MaterialProperty
          outline: true,
          outlineColor: Cesium.Color.YELLOW,
          outlineWidth: 2
        }
        Cesium.GeoJsonDataSource.load(circle).then(function (dataSource) {
          this.viewer.dataSources.add(dataSource)
          /*  const entities = dataSource.entities.values
          entities.forEach((entity) => {
            entity.polyline.material = this.outlineColor
          }) */
        })

        this.measureEnd()
      }
      // console.log('here')
      // console.log('nimabi')
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  }

  //鼠标移动事件
  mouseMoveEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure) return
      // this.viewer._element.style.cursor = 'default'
      // const position = this.viewer.scene.pickPosition(e.endPosition)
      //  if (!position)
      // {
      const position = this.viewer.scene.camera.pickEllipsoid(
        e.endPosition,
        this.viewer.scene.globe.ellipsoid
      )
      // }
      if (!position) return
      this.handleMoveEvent(position)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  //处理鼠标移动
  handleMoveEvent(position) {
    if (this.positions.length < 1) return
    // this.height = this.unifiedHeight(this.positions, this.height)
    this.tempPositions = this.positions.concat(position)
    this.createResultLabel()
  }

  //统一节点的高度
  unifiedHeight(positions, height) {
    if (!height) height = this.getPositionHeight(positions[0]) //如果没有指定高度 就用第一个的高度
    let point3d
    for (let i = 0; i < positions.length; i++) {
      const element = positions[i]
      point3d = this.cartesian3ToPoint3D(element)
      positions[i] = Cesium.Cartesian3.fromDegrees(
        point3d.x,
        point3d.y,
        height
      )
    }

    return height
  }

  //获取某个点的高度
  getPositionHeight(position) {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    return cartographic.height
  }

  cartesian3ToPoint3D(position) {
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    const lon = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)
    return {
      x: lon,
      y: lat,
      z: cartographic.height
    }
  }

  //右键事件
  rightClickEvent() {
    this.handler.setInputAction((e) => {
      if (!this.isMeasure || this.positions.length < 3) {
        this.deactivate()
        this.clear()
      } else {
        this.tempPositions = [...this.positions]
        this.polygonEntity.polyline = {
          positions: this.positions.concat(this.positions[0]),
          width: this.outlineWidth,
          material: this.outlineColor,
          depthFailMaterial: this.outlineColor
        }

        this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(
          this.tempPositions
        )
        this.polygonEntity.polygon.material = this.material
        this.mesureResultEntity.position = this.getCenterPosition()
        /*    if (this.computeArea(this.tempPositions) > 1000000)
      {
        const area = this.computeArea(this.tempPositions) / 1000000
        this.mesureResultEntity.label.text =
          area.toFixed(1) + '平方公里'
      } else
      {
        this.mesureResultEntity.label.text =
          this.computeArea(this.positions).toFixed(1) + '平方米'
      } */
        this.mesureResultEntity.label.text = this.name
        this.measureEnd()
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
  }

  //测量结束
  measureEnd() {
    this.deactivate()
    // this.MeasureEndEvent.raiseEvent(this.measureArea) //触发结束事件 传入结果
  }

  computeArea(positions) {
    const lnsLats = []

    positions[positions.length] = positions[0]
    for (let i = 0; i < positions.length; i++) {
      const cartographic = Cesium.Cartographic.fromCartesian(positions[i])
      const lng = Cesium.Math.toDegrees(cartographic.longitude)
      const lat = Cesium.Math.toDegrees(cartographic.latitude)
      lnsLats.push([lng, lat])
    }
    if (lnsLats.length >= 4) {
      const polygon = turf.polygon([

        lnsLats
      ])
      this.measureArea = turf.area(polygon)
      return this.measureArea
    } else {
      return 200
    }
  }

  //解除鼠标事件
  unRegisterEvents() {
    // this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}
